iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 12
0
自我挑戰組

Codewars Ruby Challenge in 30 Days系列 第 12

Codewars Ruby Challenge - Day 12/30

  • 分享至 

  • xImage
  •  

學習

  1. 想對 Hash 做 map 請先等等:如果最後還是想拿到 Hash,用 map 真的會很搞剛,用 map 就是想改變既有的內容物,ruby 很貼心的早就提供方法「transform_values」
  2. 堅持想用 map 怎麼寫:查到文章,提到這樣的寫法「hash.map { |k, v| [k, v.method] }.to_h」,這樣最後還是能拿到 hash
  3. 如何確保變數相除下有小數點時能正常顯示:在 ruby 裡執行「5/2」會得到「2」,除非寫成「5/2.0」,只要你給整數它就會只給你整數。但如果是變數呢「pay / people」,總不能先補個 .0 啊,龍哥有提到可以寫成「pay / people.to_f」

題目:

# 一夥人去吃飯,大家先各自付帳,待後續再計算多退少補,請根據輸出結果完成以下實作。
def split_the_bill(bill)
  # 實作內容
end

答案需要過以下測試:

RSpec.describe do
  it "帳單計算" do
    expect(split_the_bill('A' => 20, 'B' => 15, 'C' => 10)).to eq({'A' => 5.00, 'B' => 0.00, 'C' => -5.00})
    expect(split_the_bill('A' => 40, 'B' => 25, 'X' => 10)).to eq({'A' => 15.00, 'B' => 0.00, 'X' => -15.00})
  end
end

我的答案

def split_the_bill(bill)
  avg_pay = bill.values.sum / 3
  bill.map { |k, v| [k, ("%.1f" % (v - avg_pay)).to_i] }.to_h
end

思路:

  1. 先思考最終需要的是先把題目給的 hash values 減掉所有 values 值相加除以 3
  2. 先做了 avg_pay 紀錄每個人平均付費,再用 map 去達成 values 值減除 avg_pay,還好之前刷題有先學過「如何顯示到小數點後第一位」
  3. 最難的是 map 之後是 array,但答案需要的還是 hash,也是爬到文章才知道如何做到「hash map 後還是可以拿到 hash」

龍哥建議的答案

def split_the_bill(bill)
  avg = bill.values.sum / bill.count.to_f
  bill.transform_values { |v| v - avg }
end

(當發現原來 ruby 早就有適合的方法,就會覺得 OOXX……世界真美好~)


上一篇
Codewars Ruby Challenge - Day 11/30
下一篇
Codewars Ruby Challenge - Day 13/30
系列文
Codewars Ruby Challenge in 30 Days30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言